package org.electrode.task;

import org.electrode.common.Variable;

public abstract class PeriodicTask {
	volatile PeriodicTask next;
	
	//Return task if more to do otherwise, null if done
	public final PeriodicTask step() {
		if (doWork())
			return next;
		else
			return this;
	}
	
	public final PeriodicTask thenDo(PeriodicTask another) {
		this.next = another;
		return another;
	}
	
	public final PeriodicTask thenWait(long ms) {
		return thenDo(new WaitTask(ms));
	}
	
	public final PeriodicTask thenSetTo(Variable variable, double value) {
		return thenDo(new VariableSetter(variable, value));
	}
	
	public final PeriodicTask thenSetTo(Variable target, Variable source) {
		return thenDo(new VariableTransfer(target, source));
	}
	
	public final void reset() {
		doReset();
		if (null != next) next.reset();
	}
	
	public void doReset() {
	}
	
	public abstract PeriodicTask copy();
	
	public abstract boolean doWork();

	public final PeriodicTask thenTimes(int iterations, PeriodicTask each, PeriodicTask between) {
		PeriodicTask current = this;
		for (int i=0; i < iterations; i++) {
			if (0 != i)
				current = current.thenDo(between.copy());
			current = current.thenDo(each.copy());
		}
		return current;
	}
}
